import patchVNode from "./patchVNode";
import createElement from "./createElement";
const checkSame = (a, b) => {
    return a.sel == b.sel && a.key == b.key
}
export default function updateChildren(parElm, oldCh, newCh) {
    // 这里使用精细化比较
    /*
    * 前前比较
    * 后后比较
    * 新后与旧前比较
    * 新前与旧后比较
    * 新节点先比较完则说明有删除子节点
    * 旧节点先比较完则说明新增子节点
    * */
    let newStartIdx = 0     // 新前指针

    let newEndIdx = newCh.length - 1    // 新后指针

    let oldStartIdx = 0  // 旧前指针

    let oldEndIdx = oldCh.length - 1    // 旧后指针

    let newStartVNode = newCh[newStartIdx] // 新前节点

    let newEndVNode = newCh[newEndIdx] // 新后节点

    let oldStartVNode = oldCh[oldStartIdx] // 旧前指针

    let oldEndVNode = oldCh[oldEndIdx] // 旧后指针

    let keyMap = null //设置keyMap

    while(newStartIdx <= newEndIdx && oldStartIdx <= oldEndIdx) {
        console.log('newStartIdx',newStartIdx)
        console.log('oldStartIdx',oldStartIdx)
        console.log('***')
        if(newStartVNode == null || newCh[newStartIdx] == undefined){
            newStartVNode = newCh[++newStartIdx]
        } else if (newEndVNode == null || newCh[newEndIdx] == undefined) {
            newEndVNode = newCh[--newEndIdx]
        } else if (oldStartVNode == null || oldCh[oldStartIdx] == undefined) {
            oldStartVNode = oldCh[++oldStartIdx]
        } else if (oldEndVNode == null || oldCh[oldEndIdx] == undefined) {
            oldEndVNode = oldCh[--oldEndIdx]
        }
        // 前前命中
        else if(checkSame(newStartVNode,oldStartVNode)) {
            console.log('前前命中')
            patchVNode(oldStartVNode, newStartVNode)
            newStartVNode = newCh[++newStartIdx]
            oldStartVNode = oldCh[++oldStartIdx]
        }

        // 后后命中
        else if(checkSame(newEndVNode, oldEndVNode)) {
            console.log('后后命中')
            patchVNode(oldEndVNode, newEndVNode)
            newEndVNode = newCh[--newEndIdx]
            oldEndVNode = oldCh[--oldEndIdx]
        }

        // 新后与旧前
        else if(checkSame(newEndVNode, oldStartVNode)) {
            console.log('新后与旧前命中')
            patchVNode(oldStartVNode, newEndVNode)
            parElm.insertBefore(oldStartVNode.elm, oldEndVNode.elm.nextSibling)
            newEndVNode = newCh[--newEndIdx]
            oldStartVNode = oldCh[++oldStartIdx]
        }

        // 新前与旧后
        else if(checkSame(newStartVNode, oldEndVNode)) {
            console.log('新前与旧后命中')
            patchVNode(oldEndVNode, newStartVNode)
            parElm.insertBefore(oldEndVNode.elm,oldStartVNode.elm)
            newStartVNode = newCh[++newStartIdx]
            oldEndVNode = oldCh[--oldEndIdx]
        }

        else {
            // 四种都没命中
            console.log('四种都没命中')
            if(!keyMap) {
                keyMap = {}
                // 遍历旧节点
                for (let i = oldStartIdx; i <= oldEndIdx; i++) {
                    const key = oldCh[i].key
                    if (key) {
                        keyMap[key] = i
                    }
                }
                }
                let idxInOld = keyMap[newStartVNode.key] // 获取未匹配的当前项\
                if(idxInOld) {
                    console.log('这只是移动节点')
                    let moveToNode = oldCh[idxInOld]
                    patchVNode(moveToNode, newStartVNode)    // 当前移动项与新节点中匹配项对比
                    // 如果存在则只是移动位置
                    parElm.insertBefore(moveToNode.elm, oldStartVNode.elm)
                    oldCh[idxInOld] = null // 将该项设置喂undefined
                } else {
                    console.log('这只是新增节点')
                    // 如果不存在则是新增
                    parElm.insertBefore(createElement(newStartVNode),oldStartVNode.elm)    // 新增到旧前之前
                }
                newStartVNode = newCh[++newStartIdx] // 指针下移
        }
    }

    // 此处处理旧节点先遍历完
    if(newStartIdx <= newEndIdx){
        console.log('旧节点先遍历完，这是新增')
        // 新增节点
        for (let i = newStartIdx; i <= newEndIdx; i++ ) {
            parElm.insertBefore(createElement(newCh[i]),oldCh[oldStartIdx] ? oldCh[oldStartIdx].elm : null)
        }
    }
    // 此处处理新节点先遍历完
    else if (oldStartIdx <= oldEndIdx) {
        console.log('新节点先遍历完，这是删除')
        // 删除节点
        for (let i = oldStartIdx; i <= oldEndIdx; i++ ) {
            if(oldCh[i]) {
                parElm.removeChild(oldCh[i].elm)
            }
        }
    }
}
